#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS


#include "event2/event.h"
#include <stdlib.h>

#ifdef _WIN32
#include <WinSock2.h>
#endif

#define LINKS 5000
#define IP "127.0.0.1"
#define PORT 54321

struct Header
{
	int size;
	int version;
	int seq;
	int event;
	int code;
	int cmd;
};

struct Login
{
	struct Header header;
	int busiID;
	char sign[32];
};

struct event_base* base;
struct event* myEvents[LINKS][2];
SOCKET sock[LINKS];
struct sockaddr_in sockAddr;
struct timeval tv;
struct Login login;
struct Header header;

void recvCB(int sock, short events, void* arg)
{
	int num = (int)arg;
	char buff[1024] = { 0 };
	int len = recv(sock, buff, sizeof(buff), 0);
	if (len > 0)
	{
		printf("recv%d:%s\n", num, buff);
	}
	else
	{
		struct sockaddr_in temp;
		int slen = sizeof(struct sockaddr_in);
		getsockname(sock,&temp,&slen);
		printf("%d\n",ntohs(temp.sin_port));
		if (len == 0)
		{
			printf("recv%d is zero.\n",num);

		}
		else
		{
			printf("recv%d error:%d\n", num, GetLastError());	

		}
		event_del(myEvents[num][0]);
		event_del(myEvents[num][1]);
	}
}

void heartBeatCB(int sock, short events, void* arg)
{
	int num = (int)arg;
	send(sock, &header, sizeof(header), 0);
	printf("heartBeat%d\n",num);
	event_add(myEvents[num][1], &tv);
}

int main() 
{
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.S_un.S_addr = inet_addr(IP);
	sockAddr.sin_port = htons(PORT);
	login.header.size = sizeof(struct Login);
	login.header.version = 0;
	login.header.seq = 0;
	login.header.event = 0;
	login.header.code = 0;
	login.header.cmd = 2501;
	memset(login.sign,'x',32);
	//strcpy(login.sign, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
	header.size = sizeof(struct Header);
	header.version = 0;
	header.seq = 0;
	header.event = 0;
	header.code = 0;
	header.cmd = 2502;
	tv.tv_sec = 1;
	tv.tv_usec = 0;
	base = event_base_new();
	for (int i = 0; i < LINKS; ++i)
	{
		sock[i] = socket(AF_INET, SOCK_STREAM, 0);
		if (sock[i] < 0)
		{
			perror("sock");
			return -1;
		}
		else
		{
			printf("sock%d success.\n", i);
		}
		if (connect(sock[i], (struct sockaddr*)&sockAddr, sizeof(struct sockaddr)) == -1)
		{
			perror("conn");
			closesocket(sock[i]);
			return -2;
		}
		else
		{
			printf("conn%d success.\n", i);
		}
		login.busiID = i;
		send(sock[i], &login, sizeof(struct Login), 0);
		printf("login%d\n",i);
		myEvents[i][0] = event_new(base, sock[i], EV_READ | EV_PERSIST, recvCB, i);
		myEvents[i][1] = event_new(base, sock[i], EV_TIMEOUT, heartBeatCB, i);
		event_add(myEvents[i][0], NULL);
		event_add(myEvents[i][1], &tv);
	}
	event_base_dispatch(base);
	WSACleanup();
	for (int i = 0; i < LINKS; ++i) 
	{
		for (int j = 0; j < 2; ++j) 
		{
			free(myEvents[i][j]);
		}
	}
	free(base);
	return 0;
}